
package com.be.beadmin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.service.dto.input.DictDataDto;
import com.be.beadmin.service.dto.input.DictTypeDataDto;
import com.be.beadmin.service.dto.output.DictDataEx;
import com.be.beadmin.service.entity.DictData;
import com.be.beadmin.service.entity.DictData_;
import com.be.beadmin.service.entity.DictType;
import com.be.beadmin.service.entity.DictTypeEntity;
import com.be.beadmin.service.mapper.DictDataMapper;
import com.be.beadmin.service.mapper.DictDataMapperEx;
import com.be.beadmin.service.repository.DictDataRepository;
import com.be.beadmin.service.service.DictDataService;
import com.be.beadmin.service.service.DictTypeService;
import com.be.beadmin.service.service.SerialNumberService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author zjm
 * @description 服务实现
 * @date 2023-02-02
 **/
@Service
@RequiredArgsConstructor
public class DictDataServiceImpl implements DictDataService {

    @Autowired
    private DictDataRepository dictDataRepository;
    @Autowired
    private DictDataMapper dictDataMapper;
    @Autowired
    private DictDataMapperEx dictDataExMapper;
    @Autowired
    private DictTypeService dictTypeService;

    @Autowired
    private SerialNumberService serialNumberService;

    @Override
    public Page<DictDataEx> getDictDataByPage(PageEntity pageEntity) {
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<DictData> page = dictDataRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(DictData_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(DictData_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<DictDataEx> page1 = page.map(dictDataExMapper::toEntity);
        return page1;

    }

    @Override
    public void addDictData(DictDataDto dictDataDto) {
        DictData result = dictDataRepository.findDictDataByIdAndDelete(dictDataDto.getId(), 0);
        if (ObjectUtil.isNotEmpty(result)) {
            throw new BeadminException("DictData不存在,请重新查询");
        }
        // 设置字典数据编码
        String code = serialNumberService.getNextSnByCode("DictDataCode");
        dictDataDto.setSerialNo(code);
//        dictDataDto.setDictTypeId();
        DictData dictData = dictDataMapper.toEntity(dictDataDto);
        dictData.setDictTypeId(dictDataDto.getDictTypeId());
        dictDataRepository.save(dictData);
    }

    @Override
    public void updateDictData(DictDataDto dictDataDto) {
        DictData dictDataById = dictDataRepository.findDictDataById(dictDataDto.getId());
        DictData dictData = dictDataMapper.toEntity(dictDataDto);
        dictData.setSerialNo(dictDataById.getSerialNo());
        dictData.setDictSort(dictDataById.getDictSort());
        dictData.setDictTypeId(dictDataById.getDictTypeId());
//        dictData.setDictType(dictDataDto.getDictTypeId());
        dictDataRepository.save(dictData);
    }


    @Override
    public void delDictData(String id) {
        DictData dictData = dictDataRepository.findDictDataById(id);
        dictData.setDelete(1);
        dictDataRepository.save(dictData);
    }

    @Override
    public void delDictDatas(List<String> ids) {
    }

    @Override
    public List<DictDataEx> getDictDataExByDictTypeId(DictType dictType) {
//        System.out.println("dictType:"+dictType);
        List<DictData> dictDataList = dictDataRepository.findDictDataByDictTypeId(dictType.getId());
//        System.out.println("dictDataList:"+dictDataList);
        return dictDataExMapper.toEntity(dictDataList);
    }

    @Override
    public List<DictData> getDictDataByDictTypeId(DictType dictType) {
//        System.out.println("dictType:"+dictType);
        List<DictData> dictDataList = dictDataRepository.findDictDataByDictTypeId(dictType.getId());
//        System.out.println("dictDataList:"+dictDataList);
        return dictDataList;
    }

    @Override
    public List<String> getDictDataKeyNameByDictTypeId(DictType dictType) {

        List<DictData> dictDataList = dictDataRepository.findDictDataByDictTypeId(dictType.getId());

        return null;
    }

    @Override
    public HashMap<String, String> getDictDataMapByDictTypeId(DictType dictType) {
        List<DictData> dictDatas = dictDataRepository.findDictDataByDictTypeIdAndDelete(dictType.getId(), 0);
        if (ObjectUtil.isEmpty(dictDatas)) {
            return null;
        }
        HashMap<String, String> dictDataMap = new HashMap<>();
        dictDatas.forEach(dictData -> dictDataMap.put(dictData.getKeyName(), dictData.getKeyValue()));

        return dictDataMap;
    }

    public HashMap<String, String> getDictDataMapByDictTypeName(String dictTypeName) {
        DictType dictType = dictTypeService.getDictTypeByName(dictTypeName);

        List<DictData> dictDatas = dictDataRepository.findDictDataByDictTypeIdAndDelete(dictType.getId(), 0);
        if (ObjectUtil.isEmpty(dictDatas)) {
            return null;
        }
        HashMap<String, String> dictDataMap = new HashMap<>();
        dictDatas.forEach(dictData -> dictDataMap.put(dictData.getKeyName(), dictData.getKeyValue()));

        return dictDataMap;
    }

    public List<String> getDictDataKeyByDictTypeName(String dictTypeName) {
        DictType dictType = dictTypeService.getDictTypeByName(dictTypeName);

        List<DictData> dictDatas = dictDataRepository.findDictDataByDictTypeIdAndDelete(dictType.getId(), 0);
        if (ObjectUtil.isEmpty(dictDatas)) {
            return null;
        }
        List<String> dictDataList = new ArrayList<>();

        dictDatas.forEach(dictData -> dictDataList.add(dictData.getKeyName()));

        return dictDataList;
    }

    /**
     * 添加一条字典数据通过Id
     *
     * @param dictDataDto
     */
    @Override
    public void addDictDataByDictTypeId(DictTypeDataDto dictDataDto) {
        DictData dictData = new DictData();
        String dictTypeId = dictDataDto.getDictTypeId();
        DictDataDto dictDataDto1 = dictDataDto.getDictDataDto();
        DictData result = dictDataRepository.findDictDataByIdAndDelete(dictDataDto1.getId(), 0);
        if (ObjectUtil.isNotEmpty(result)) {
            throw new BeadminException("DictData不存在,请重新查询");
        }
        // 设置字典数据编码
        String code = serialNumberService.getNextSnByCode("DictDataCode");
        dictData.setSerialNo(code);
        dictData.setDictTypeId(dictTypeId);
        dictData.setDictSort(dictDataDto1.getDictSort());
        dictData.setKeyName(dictDataDto1.getKeyName());
        dictData.setKeyValue(dictDataDto1.getKeyValue());
        dictData.setReserved(dictDataDto1.getReserved());
        dictData.setMemo(dictDataDto1.getMemo());
//        dictDataDto.setDictTypeId();
        dictDataRepository.save(dictData);
    }

    @Override
    public Page<DictDataEx> getDictDataByPageAndDictType(DictTypeEntity dictTypeEntity) {
//        if (dictTypeEntity.getDictTypeId() )
        PageEntity pageEntity = dictTypeEntity.getPageEntity();
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<DictData> page = dictDataRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(DictData_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate pre3 = criteriaBuilder.equal(root.get(DictData_.dictTypeId), dictTypeEntity.getDictTypeId()); //过滤为0
                    list.add(pre3);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(DictData_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<DictDataEx> page1 = page.map(dictDataExMapper::toEntity);
        return page1;
    }
}